/**
 * ReportGear(2011)
 */
package net.abbp.report.view.grid;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.KeyStroke;

import net.abbp.report.model.ReportModel;
import net.abbp.report.view.GridView;

import com.reportgear.report.view.grid.selection.GridSelection;
import com.reportgear.report.view.grid.selection.Selection;
import com.reportgear.report.view.grid.util.GridUtils;

/**
 * Grid操作管理
 * 
 * @version 1.0 2011-3-21
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */

@SuppressWarnings("serial")
class GridAction {
    private final Grid grid;
    private GridView gridView;

    GridAction(Grid grid) {
        this.grid = grid;
        this.gridView = grid.gridView;

        this.initGrid(grid);
    }

    private final Action downAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.downKeyPressed(false);
        }
    };

    private final Action downShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.downKeyPressed(true);
        }
    };

    private final Action enterAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.enterActionMoveDirectoin(false);
        }
    };

    private final Action enterShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.enterActionMoveDirectoin(true);
        }
    };

    private final Action leftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.leftKeyPressed(false);
        }
    };
    private final Action leftShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.leftKeyPressed(true);
        }
    };
    private final Action rightAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.rightKeyPressed(false);
        }
    };
    private final Action rightShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.rightKeyPressed(true);
        }
    };
    private final Action tabAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.tabActionMoveDirectoin(false);
        }
    };
    private final Action tabShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.tabActionMoveDirectoin(true);
        }
    };
    private final Action upAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.upKeyPressed(false);
        }
    };
    private final Action upShiftAction = new AbstractAction() {

        public void actionPerformed(ActionEvent evt) {
            GridAction.this.upKeyPressed(true);
        }
    };

    void downKeyPressed(boolean isShift) {
        Selection sel;
        GridView gridView = this.grid.gridView;
        GridSelection gridSel = this.gridView.getGridSelection();

        if (isShift) {
            sel = gridSel.getEditSelection();
            Selection sel2 = gridSel.getLastCellSelection();
            if (!(shiftDown(gridView, sel, sel2))) {
                return;
            }
        } else {
            sel = gridSel.getEditSelection();

            int nextRow = sel.getRow() + sel.getRowSpan();

            GridUtils.doSelectCell(gridView, sel.getColumn(), nextRow);
        }

        gridView.refresh();
    }

    void enterActionMoveDirectoin(boolean paramBoolean) {
        if (grid.isCellEditing()) {
            grid.stopEditing();
        }

        ReportModel localReport = this.gridView.getReportModel();
        GridSelection gridSelection = this.gridView.getGridSelection();

        int j = 3;
        int k = grid.getEnterMoveDirection();
        if (k != 0) {
            j = k;
        }

        Selection selection1 = gridSelection.getEditSelection();
        Selection selection2 = gridSelection.getLastCellSelection();
        tabEnterMoveDirection(paramBoolean, this.gridView, selection1, selection2, j);
        this.gridView.repaint();
    }

    private void initGrid(Grid grid) {
        final InputMap inputMap = grid.getInputMap();
        final ActionMap actionMap = grid.getActionMap();

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
        actionMap.put("left", this.leftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.SHIFT_DOWN_MASK), "left_shift");
        actionMap.put("left_shift", this.leftShiftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
        actionMap.put("right", this.rightAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.SHIFT_DOWN_MASK), "right_shift");
        actionMap.put("right_shift", this.rightShiftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
        actionMap.put("up", this.upAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_DOWN_MASK), "up_shift");
        actionMap.put("up_shift", this.upShiftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");
        actionMap.put("down", this.downAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_DOWN_MASK), "down_shift");
        actionMap.put("down_shift", this.downShiftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
        actionMap.put("enter", this.enterAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK), "enter_shift");
        actionMap.put("enter_shift", this.enterShiftAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "tab");
        actionMap.put("tab", this.tabAction);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), "tab_shift");
        actionMap.put("tab_shift", this.tabShiftAction);
    }

    void leftKeyPressed(boolean isShift) {
        Selection sel;
        GridView gridView = this.grid.gridView;
        GridSelection gridSel = gridView.getGridSelection();

        if (isShift) {
            sel = gridSel.getEditSelection();
            final Selection localRectangle2 = gridSel.getLastCellSelection();
            if (this.shiftLeft(gridView, sel, localRectangle2)) {
                gridView.repaint();
            }
            // localReportPane.fireGridSelectionChanged();

        } else {
            sel = gridSel.getEditSelection();
            if (sel.getColumn() <= 0) {
                return;
            }

            int col = sel.getColumn() - 1;
            GridUtils.doSelectCell(gridView, col, sel.getRow());

            gridView.repaint();
        }

    }

    void rightKeyPressed(boolean isShift) {
        Selection sel;
        final GridView grdView = this.grid.gridView;
        final GridSelection gridSel = grdView.getGridSelection();

        if (isShift) {
            sel = gridSel.getEditSelection();
            Selection localRectangle2 = gridSel.getLastCellSelection();
            if (this.shiftRight(grdView, sel, localRectangle2)) {
                grdView.repaint();
            }
            // lgrdView.fireGridSelectionChanged();

        } else {
            sel = gridSel.getEditSelection();
            int col = sel.getColumn() + sel.getColumSpan();
            GridUtils.doSelectCell(grdView, col, sel.getRow());

            grdView.repaint();
        }

    }

    protected boolean shiftLeft(GridView paramReportPane, Selection paramRectangle1, Selection paramRectangle2) {
        // Rectangle localRectangle1;
        // Rectangle localRectangle2;
        //
        // ReportModel report = worksheet.getReportModel();
        // int i = paramRectangle1.getColumn() + paramRectangle1.getColumSpan()
        // - 1;
        // int j = paramRectangle2.getColumn() + paramRectangle2.getColumSpan()
        // - 1;
        // if (j > i) {
        // localRectangle1 = caculateIntersectsUnion(report, new Rectangle(j,
        // paramRectangle2.getRow(), 1,
        // paramRectangle2.getRowSpan()));
        // if (ReportUtils.contains(localRectangle1.x, localRectangle1.y,
        // localRectangle1.width,
        // localRectangle1.height, paramRectangle1.x, paramRectangle1.y,
        // paramRectangle1.width,
        // paramRectangle1.height)) {
        // if (paramRectangle1.x <= 0) {
        // return false;
        // }
        //
        // localRectangle2 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x - 1,
        // paramRectangle2.y, paramRectangle2.width + 1,
        // paramRectangle2.height));
        // Rectangle localRectangle3 = localRectangle2.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle3.x, localRectangle3.y,
        // localRectangle3.width,
        // localRectangle3.height);
        // } else {
        // paramRectangle2.width = (localRectangle1.x - paramRectangle2.x);
        // }
        //
        // } else {
        // if (paramRectangle2.x <= 0) {
        // return false;
        // }
        //
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x - 1,
        // paramRectangle2.y, paramRectangle2.width + 1,
        // paramRectangle2.height));
        // localRectangle2 = localRectangle1.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle2.x, localRectangle2.y,
        // localRectangle2.width,
        // localRectangle2.height);
        // }

        return true;
    }

    protected boolean shiftRight(GridView paramReportPane, Selection paramRectangle1, Selection paramRectangle2) {
        Rectangle localRectangle1;
        Rectangle localRectangle2;
        //
        // ReportModel localReport = paramReportPane.getReportModel();
        // if (paramRectangle2.x < paramRectangle1.x) {
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // 1, paramRectangle2.height));
        // if (ReportUtils.contains(localRectangle1.x, localRectangle1.y,
        // localRectangle1.width,
        // localRectangle1.height, paramRectangle1.x, paramRectangle1.y,
        // paramRectangle1.width,
        // paramRectangle1.height)) {
        // if ((paramRectangle2.x + paramRectangle2.width >
        // localReport.getColumnCount() - 1)) {
        // return false;
        // }
        //
        // localRectangle2 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x,
        // paramRectangle2.y, paramRectangle2.width + 1,
        // paramRectangle2.height));
        // Rectangle localRectangle3 = localRectangle2.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle3.x, localRectangle3.y,
        // localRectangle3.width,
        // localRectangle3.height);
        // } else {
        // paramRectangle2.width = (paramRectangle2.x + paramRectangle2.width -
        // (localRectangle1.x + localRectangle1.width));
        // paramRectangle2.x = (localRectangle1.x + localRectangle1.width);
        // }
        //
        // } else {
        // if ((paramRectangle2.x + paramRectangle2.width >
        // localReport.getColumnCount() - 1)) {
        // return false;
        // }
        //
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width + 1, paramRectangle2.height));
        // localRectangle2 = localRectangle1.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle2.x, localRectangle2.y,
        // localRectangle2.width,
        // localRectangle2.height);
        // }

        return true;
    }

    void tabActionMoveDirectoin(boolean paramBoolean) {
        if (this.grid.isCellEditing()) {
            this.grid.stopEditing();
        }

        final GridView localReportPane = this.grid.gridView;
        final GridSelection localGridSelection = localReportPane.getGridSelection();

        int j = 4;
        final int k = this.grid.getTabMoveDirection();
        if (k != 0) {
            j = k;
        }

        final Selection localRectangle1 = localGridSelection.getEditSelection();
        final Selection localRectangle2 = localGridSelection.getEditSelection();
        this.tabEnterMoveDirection(paramBoolean, localReportPane, localRectangle1, localRectangle2, j);
        localReportPane.repaint();
    }

    private void tabEnterMoveDirection(boolean paramBoolean, GridView paramReportPane, Selection paramRectangle1,
            Selection paramRectangle2, int paramInt) {
        if (paramInt == 3) {
            if (paramBoolean) {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn(), paramRectangle1.getRow() - 1);
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x,
                // paramRectangle1.y - 1);
            } else {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn(), paramRectangle1.getRow()
                        + paramRectangle1.getRowSpan());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x,
                // paramRectangle1.y + paramRectangle1.height);
            }

        } else if (paramInt == 4) {
            if (paramBoolean) {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn() - 1, paramRectangle1.getColumn());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x - 1,
                // paramRectangle1.y);
            } else {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn() + paramRectangle1.getColumSpan(),
                        paramRectangle1.getRow());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x +
                // paramRectangle1.width, paramRectangle1.y);
            }

        } else if (paramInt == 1) {
            if (paramBoolean) {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn(), paramRectangle1.getRow()
                        + paramRectangle1.getRowSpan());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x,
                // paramRectangle1.y + paramRectangle1.height);
            } else {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn(), paramRectangle1.getRow() - 1);
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x,
                // paramRectangle1.y - 1);
            }

        } else {
            if (paramInt != 2) {
                return;
            }

            if (paramBoolean) {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn() + paramRectangle1.getColumSpan(),
                        paramRectangle1.getRow());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x +
                // paramRectangle1.width, paramRectangle1.y);
            } else {
                GridUtils.doSelectCell(paramReportPane, paramRectangle1.getColumn() - 1, paramRectangle1.getRow());
                // paramReportPane.ensureColumnRowVisible(paramRectangle1.x - 1,
                // paramRectangle1.y);
            }

        }
    }

    void upKeyPressed(boolean isShift) {
        Selection sel;
        GridView gridView = this.gridView;
        GridSelection gridSel = gridView.getGridSelection();

        if (isShift) {
            sel = gridSel.getEditSelection();
            Selection localRectangle2 = gridSel.getLastCellSelection();
            if (shiftUp(gridView, sel, localRectangle2)) {
                gridView.repaint();
            }
            // localReportPane.fireGridSelectionChanged();

        } else {
            sel = gridSel.getEditSelection();
            if (sel.getRow() <= 0) {
                return;
            }

            int nextRow = sel.getRow() - 1;
            GridUtils.doSelectCell(gridView, sel.getColumn(), nextRow);
            gridView.repaint();
        }
    }

    protected boolean shiftUp(GridView paramReportPane, Selection paramRectangle1, Selection paramRectangle2) {
        // Rectangle localRectangle1;
        // Rectangle localRectangle2;
        //
        // ReportModel localReport = paramReportPane.getReportModel();
        // int i = paramRectangle1.y + paramRectangle1.height - 1;
        // int j = paramRectangle2.y + paramRectangle2.height - 1;
        // if (j > i) {
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x, j,
        // paramRectangle2.width, 1));
        // if (ReportUtils.contains(localRectangle1.x, localRectangle1.y,
        // localRectangle1.width,
        // localRectangle1.height, paramRectangle1.x, paramRectangle1.y,
        // paramRectangle1.width,
        // paramRectangle1.height)) {
        // if (paramRectangle2.y <= 0) {
        // return false;
        // }
        //
        // localRectangle2 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x,
        // paramRectangle2.y - 1, paramRectangle2.width, paramRectangle2.height
        // + 1));
        // Rectangle localRectangle3 = localRectangle2.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle3.x, localRectangle3.y,
        // localRectangle3.width,
        // localRectangle3.height);
        // } else {
        // paramRectangle2.height = (localRectangle1.y - paramRectangle2.y);
        // }
        //
        // } else {
        // if (paramRectangle2.y <= 0) {
        // return false;
        // }
        //
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x,
        // paramRectangle2.y - 1, paramRectangle2.width, paramRectangle2.height
        // + 1));
        // localRectangle2 = localRectangle1.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle2.x, localRectangle2.y,
        // localRectangle2.width,
        // localRectangle2.height);
        // }

        return true;
    }

    protected boolean shiftDown(GridView paramReportPane, Selection paramRectangle1, Selection paramRectangle2) {
        // Rectangle localRectangle1;
        // Rectangle localRectangle2;
        //
        // ReportModel localReport = paramReportPane.getReportModel();
        // if (paramRectangle2.y < paramRectangle1.y) {
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, 1));
        // if (ReportUtils.contains(localRectangle1.x, localRectangle1.y,
        // localRectangle1.width,
        // localRectangle1.height, paramRectangle1.x, paramRectangle1.y,
        // paramRectangle1.width,
        // paramRectangle1.height)) {
        // if ((paramRectangle2.y + paramRectangle2.height >
        // localReport.getRowCount() - 1)) {
        // return false;
        // }
        //
        // localRectangle2 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x,
        // paramRectangle2.y, paramRectangle2.width, paramRectangle2.height +
        // 1));
        // Rectangle localRectangle3 = localRectangle2.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle3.x, localRectangle3.y,
        // localRectangle3.width,
        // localRectangle3.height);
        // } else {
        // paramRectangle2.height = (paramRectangle2.y + paramRectangle2.height
        // - (localRectangle1.y + localRectangle1.height));
        // paramRectangle2.y = (localRectangle1.y + localRectangle1.height);
        // }
        //
        // } else {
        // if ((paramRectangle2.y + paramRectangle2.height >
        // localReport.getRowCount() - 1)) {
        // return false;
        // }
        //
        // localRectangle1 = caculateIntersectsUnion(localReport, new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height + 1));
        // localRectangle2 = localRectangle1.union(new
        // Rectangle(paramRectangle2.x, paramRectangle2.y,
        // paramRectangle2.width, paramRectangle2.height));
        // paramRectangle2.setBounds(localRectangle2.x, localRectangle2.y,
        // localRectangle2.width,
        // localRectangle2.height);
        // }

        return true;
    }
}
